-
Notifications
You must be signed in to change notification settings - Fork 355
Cap total number of concurrent commands per connection #592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Cap total number of concurrent commands per connection #592
Conversation
|
@arturobernalg I do not like this approach. There is already a command queue built into the |
de6f206 to
b777f5d
Compare
@ok2c . Sorry about the churn — I’m still getting up to speed on this part of the reactor stack and my previous commit took a wrong turn. I dropped the extra wrapper and enforce the cap via the existing |
httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSession.java
Outdated
Show resolved
Hide resolved
| * @return {@code true} if the command was enqueued, {@code false} otherwise. | ||
| * @since 5.5 | ||
| */ | ||
| default boolean enqueue(final Command command, final Command.Priority priority, final int maxPendingCommands) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg I would not do that on the i/o session level. Different protocol handlers may have different restrictions. 10 concurrent requests may be perfectly OK for HTTP/2 and too much for HTTP/1.1. Please move this logic to individual protocol handlers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ok2c I just drop the IOSession-level enqueue/queue-limit API and keep the cap/reject logic strictly in the HTTP/2 requester/handler layer as requested.
3cbecbe to
639e632
Compare
...5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java
Outdated
Show resolved
Hide resolved
9c8911c to
e6cb499
Compare
...5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java
Outdated
Show resolved
Hide resolved
ok2c
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg Conceptually everything looks good to me. However as far as I can see you are also mixing in some code optimization into the same change-set.
Could you please do this?
- Spin the optimization code into a separate pull request. It should get merged in first.
- Re-base this pull request off it
- Provide the same logic to
HttpAsyncRequesterfor consistency.
130dedf to
8aa41be
Compare
@ok2c Please another pass |
ok2c
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg Almost there. Just a few comments.
| private final H2ConnPool connPool; | ||
|
|
||
| /** | ||
| * Hard cap on per-connection queued / in-flight requests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg Let's use the term "command" instead of "request" here to make sure there is no confusion with HTTP requests.
| final int current = ioSession.getPendingCommandCount(); | ||
| if (current >= 0 && current >= max) { | ||
| exchangeHandler.failed(new RejectedExecutionException( | ||
| "Maximum number of pending requests per connection reached (max=" + max + ")")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg Same as above. Let say "command" instead of "request" here
|
|
||
| private IOReactorMetricsListener threadPoolListener; | ||
|
|
||
| private int maxRequestsPerConnection; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg Same.
| @@ -0,0 +1,245 @@ | |||
| /* | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg Let's drop all examples and integration tests. They look heavy and require a specially crafted server side listener. I wish we had unit test coverage for HttpAsyncRequester / H2MultiplexingRequester but we do not.
This functionality can have integration tests and examples in client along with other client request per connection policy configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ok2c done
7ddd29a to
756d5a4
Compare
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.api.Timeout; | ||
|
|
||
| class TestIOSessionImplMaxPendingCommands { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg I am not sure what this test is actually testing. Let's drop it and the other test as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleted
Restore per-session command count and use it in H2MultiplexingRequester to fail fast when the per-connection command queue exceeds the configured limit.
186431e to
22d2ea5
Compare
| import org.junit.jupiter.api.Assertions; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| class TestH2MultiplexingRequesterMaxRequestsPerConnection { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg This test should be moved to client and be made a part of a larger suite of related integration tests, but if you want to keep it here, so be it, but at least be consistent and provide a similar one for HttpAsyncRequester.
This change adds an optional hard cap on the number of pending request execution commands queued per HTTP/2 connection. When the per-connection limit is reached, new submissions fail fast with RejectedExecutionException and the exchange handler releases its resources immediately. The cap is configured via H2MultiplexingRequesterBootstrap and passed into H2MultiplexingRequester at construction time to keep requester configuration immutable and avoid API incompatibilities.